package com.sumer.psychology.tag.infrastructure.persistence.mongo;

import com.mongodb.BasicDBList;
import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;
import com.mongodb.util.JSON;
import com.sumer.psychology.common.BusinessException;
import com.sumer.psychology.common.persistence.mongodb.AbstractMongoRepository;
import com.sumer.psychology.common.persistence.mongodb.MongoEventUtil;

import java.util.List;

/**
 * mongo标记资源库
 * <p/>
 * User: zhenguang.zhu
 * Date: 2014/10/30
 * Time: 8:50
 */
public class MongoTagRepository extends AbstractMongoRepository {
    private static final String PREFIX = "sumer_";
    private static final String SUFFIX = "_tags";

    @Override
    protected String dbName() {
        return null;
    }

    /**
     * 增加或更新
     *
     * @param data json
     */
    public void save(String data, String type) {
        DBObject tags = MongoEventUtil.filterEventObject((DBObject) JSON.parse(data));
        String hostId = nestedValue(tags, type + "Id.identity");

        removeTags(tags, hostId, type);
        updateTag(tags, hostId, type);
    }

    /*
     * 更新Tag文档
     */
    private void updateTag(DBObject dbTags, String hostId, String type) {
        List tags = (List) dbTags.get("tags");
        for (Object tag : tags) {
            String tagName = (String) ((DBObject) tag).get("name");

            db().getCollection(PREFIX + type + SUFFIX).update(
                    new BasicDBObject("name", tagName),
                    new BasicDBObject("$addToSet", new BasicDBObject(type + "_ids", hostId)),
                    true,
                    false);
        }
    }

    /*
     * 从Tag文档中删除不需要的blog
     */
    private void removeTags(DBObject dbTags, String hostId, String type) {
        List removedTags = (List) dbTags.get("removedTags");
        for (Object removedTag : removedTags) {
            String tagName = (String) ((DBObject) removedTag).get("name");

            db().getCollection(PREFIX + type + SUFFIX).update(
                    new BasicDBObject("name", tagName),
                    new BasicDBObject("$pull", new BasicDBObject(type + "_ids", hostId)));
        }
    }

    /**
     * 从主业务中替换tags
     *
     * @param data json
     */
    public void replaceTags(String data, String key, String dbName) {
        DBObject dbTags = initializeData(data, key);
        List tags = (List) dbTags.get("tags");

        BasicDBList tagNames = new BasicDBList();
        for (Object tag : tags) {
            String tagName = (String) ((DBObject) tag).get("name");
            tagNames.add(tagName);
        }
        dbTags.put("tags", tagNames);
        dbTags.removeField("removedTags");

        db().getCollection(dbName).update(
                idCondition((String) dbTags.get("_id")),
                new BasicDBObject("$set", dbTags),
                true, // upsert
                false);
    }

    /**
     * 根据类型查找
     *
     * @param id          id
     * @param commentType comment type
     * @return db object
     */
    public DBObject findOneByType(String id, String commentType) {
        return db().getCollection(PREFIX + commentType + SUFFIX).findOne(new BasicDBObject("_id", id));
    }

    /**
     * 根据标签名称查询
     *
     * @param name        name
     * @param commentType comment type
     * @return db object
     */
    public DBObject findOneByName(String name, String commentType) {
        return db().getCollection(PREFIX + commentType + SUFFIX).findOne(new BasicDBObject("name", name));
    }

    /**
     * 根据类型删除
     *
     * @param id          id
     * @param commentType comment type
     */
    public void removeOneByType(String id, String commentType) {
        db().getCollection(PREFIX + commentType + SUFFIX).remove(new BasicDBObject("_id", id));
    }

    @Override
    public DBObject findOneWithStatus(String id, String availability) {
        throw new BusinessException("必须指定类型");
    }

    @Override
    public void removeOne(String id) {
        throw new BusinessException("必须指定类型");
    }
}
